



#include "dev_mpu6050.h"




//下面是IIC接口
IICdevice* device;

//IIC连续写
//addr:器件地址 
//reg:寄存器地址
//len:写入长度
//buf:数据区
//返回值:0,正常
//    其他,错误代码
unt8 MPU_Write_Len(unt8 addr, unt8 reg, unt8 len, unt8* buf)
{
	unt8 i;
	Soft_IIC_Start(device);
	//发送器件地址+写命令
	if (Soft_IIC_Send_Byte(device, (addr << 1) | 0) == NACK)	//如果无应答
	{
		Soft_IIC_Stop(device);
		return 1;
	}

	Soft_IIC_Send_Byte(device, reg);	//写寄存器地址
	for (i = 0; i < len; i++)
	{
		//发送数据
		if (Soft_IIC_Send_Byte(device, buf[i]) == NACK) {
			Soft_IIC_Stop(device);
			return 1;
		}
	}
	Soft_IIC_Stop(device);
	return 0;
}
//IIC连续读
//addr:器件地址
//reg:要读取的寄存器地址
//len:要读取的长度
//buf:读取到的数据存储区
//返回值:0,正常
//    其他,错误代码
unt8 MPU_Read_Len(unt8 addr, unt8 reg, unt8 len, unt8* buf)
{
	Soft_IIC_Start(device);
	if (Soft_IIC_Send_Byte(device, (addr << 1) | 0) == NACK) { //发送器件地址+写命令
		Soft_IIC_Stop(device);
		printfs("\r\n read failed");
		return 1;
	}

	Soft_IIC_Send_Byte(device, reg);	//写寄存器地址
	Soft_IIC_Start(device);
	Soft_IIC_Send_Byte(device, (addr << 1) | 1);//发送器件地址+读命令
	while (len)
	{
		if (len == 1)*buf = Soft_IIC_Recv_Byte(device, NACK); //读数据,发送nACK
		else *buf = Soft_IIC_Recv_Byte(device, ACK);		 //读数据,发送ACK
		len--;
		buf++;
	}
	Soft_IIC_Stop(device);	//产生一个停止条件
	return 0;
}
//IIC写一个字节
//reg:寄存器地址
//data:数据
//返回值:0,正常
//    其他,错误代码
unt8 MPU_Write_Byte(unt8 reg, unt8 data)
{
	Soft_IIC_Start(device);
	if (Soft_IIC_Send_Byte(device, (MPU_ADDR << 1) | 0) == NACK)//发送器件地址+写命令
	{
		Soft_IIC_Stop(device);
		return 1;
	}

	Soft_IIC_Send_Byte(device, reg); //写寄存器地址

	if (Soft_IIC_Send_Byte(device, data) == NACK) //发送数据，如果无应答
	{
		Soft_IIC_Stop(device);
		return 1;
	}
	Soft_IIC_Stop(device);
	return 0;
}
//IIC读一个字节
//reg:寄存器地址
//返回值:读到的数据
unt8 MPU_Read_Byte(unt8 reg)
{
	unt8 res;
	Soft_IIC_Start(device);
	Soft_IIC_Send_Byte(device, (MPU_ADDR << 1) | 0);//发送器件地址+写命令
	Soft_IIC_Send_Byte(device, reg);	//写寄存器地址
	Soft_IIC_Start(device);
	Soft_IIC_Send_Byte(device, (MPU_ADDR << 1) | 1);	//发送器件地址+读命令
	res = Soft_IIC_Recv_Byte(device, NACK);	//读取数据,发送nACK
	Soft_IIC_Stop(device);			//产生一个停止条件
	return res;
}

//  上面是硬件接口



//设置MPU6050陀螺仪传感器满量程范围
//fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps
//返回值:0,设置成功
//    其他,设置失败 
unt8 MPU_Set_Gyro_Fsr(unt8 fsr)
{
	return MPU_Write_Byte(MPU_GYRO_CFG_REG,fsr<<3);//设置陀螺仪满量程范围  
}
//设置MPU6050加速度传感器满量程范围
//fsr:0,±2g;1,±4g;2,±8g;3,±16g
//返回值:0,设置成功
//    其他,设置失败 
unt8 MPU_Set_Accel_Fsr(unt8 fsr)
{
	return MPU_Write_Byte(MPU_ACCEL_CFG_REG,fsr<<3);//设置加速度传感器满量程范围  
}
//设置MPU6050的数字低通滤波器
//lpf:数字低通滤波频率(Hz)
//返回值:0,设置成功
//    其他,设置失败 
unt8 MPU_Set_LPF(unt16 lpf)
{
	unt8 data=0;
	if(lpf>=188)data=1;
	else if(lpf>=98)data=2;
	else if(lpf>=42)data=3;
	else if(lpf>=20)data=4;
	else if(lpf>=10)data=5;
	else data=6; 
	return MPU_Write_Byte(MPU_CFG_REG,data);//设置数字低通滤波器  
}
//设置MPU6050的采样率(假定Fs=1KHz)
//rate:4~1000(Hz)
//返回值:0,设置成功
//    其他,设置失败 
unt8 MPU_Set_Rate(unt16 rate)
{
	unt8 data;
	if(rate>1000)rate=1000;
	if(rate<4)rate=4;
	data=1000/rate-1;
	data=MPU_Write_Byte(MPU_SAMPLE_RATE_REG,data);	//设置数字低通滤波器
 	return MPU_Set_LPF(rate/2);	//自动设置LPF为采样率的一半
}
//得到温度值
//返回值:温度值(扩大了100倍)
short MPU_Get_Temperature(void)
{
    unt8 buf[2];
    short raw;
	float temp;
	MPU_Read_Len(MPU_ADDR,MPU_TEMP_OUTH_REG,2,buf); 
    raw=((unt16)buf[0]<<8)|buf[1];
    temp=36.53+((double)raw)/340;  
    return temp*100;;
}
//得到陀螺仪值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
//返回值:0,成功
//    其他,错误代码
unt8 MPU_Get_Gyroscope(short *gx,short *gy,short *gz)
{
    unt8 buf[6],res;
	res=MPU_Read_Len(MPU_ADDR,MPU_GYRO_XOUTH_REG,6,buf);
	if(res==0)
	{
		*gx=((unt16)buf[0]<<8)|buf[1];
		*gy=((unt16)buf[2]<<8)|buf[3];
		*gz=((unt16)buf[4]<<8)|buf[5];
	} 	
    return res;;
}
//得到加速度值(原始值)
//gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
//返回值:0,成功
//    其他,错误代码
unt8 MPU_Get_Accelerometer(short *ax,short *ay,short *az)
{
    unt8 buf[6],res;
	res=MPU_Read_Len(MPU_ADDR,MPU_ACCEL_XOUTH_REG,6,buf);
	if(res==0)
	{
		*ax=((unt16)buf[0]<<8)|buf[1];
		*ay=((unt16)buf[2]<<8)|buf[3];
		*az=((unt16)buf[4]<<8)|buf[5];
	} 	
    return res;;
}


//初始化MPU6050
//返回值:0,成功
//    其他,错误代码
unt8 MPU_Init(void)
{
	unt8 res;

//	MPU_AD0_CTRL=0;			//控制MPU6050的AD0脚为低电平,从机地址为:0X68
//	MPU_IIC_Init();//初始化IIC总线

	MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X80);	//复位MPU6050
	mcu_delay_ms(100);

	MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X00);	//唤醒MPU6050
	MPU_Set_Gyro_Fsr(3);					//陀螺仪传感器,±2000dps
	MPU_Set_Accel_Fsr(0);					//加速度传感器,±2g
	MPU_Set_Rate(50);						//设置采样率50Hz
	MPU_Write_Byte(MPU_INT_EN_REG,0X00);	//关闭所有中断
	MPU_Write_Byte(MPU_USER_CTRL_REG,0X00);	//I2C主模式关闭
	MPU_Write_Byte(MPU_FIFO_EN_REG,0X00);	//关闭FIFO
	MPU_Write_Byte(MPU_INTBP_CFG_REG,0X80);	//INT引脚低电平有效

	res=MPU_Read_Byte(MPU_DEVICE_ID_REG);


	printfs(" mpu id: %d ",res);
	//if(res==MPU_ADDR)//器件ID正确
	{
		MPU_Write_Byte(MPU_PWR_MGMT1_REG,0X01);	//设置CLKSEL,PLL X轴为参考
		MPU_Write_Byte(MPU_PWR_MGMT2_REG,0X00);	//加速度与陀螺仪都工作
		MPU_Set_Rate(50);						//设置采样率为50Hz
 	}
	//else return 1;
	return 0;
}

//
void test_mpu6050(void)
{
	MPU_Init();					//初始化MPU6050

	while(1)
	{	
		short aacx,aacy,aacz;		//加速度传感器数据
		short gyrox,gyroy,gyroz;	//陀螺仪数据
		short temp;					//温度

		temp=MPU_Get_Temperature();	//得到温度
		MPU_Get_Accelerometer(&aacx,&aacy,&aacz);	//得到加速度传感器数据
		MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz);	//得到陀螺仪数据

		printfs("\r\n === temp : %7d,",temp);
		printfs("B acc xyz: %7d, %7d, %7d, ",aacx,aacy,aacz );
		printfs("gyr xyz: %7d, %7d, %7d, ", gyrox,gyroy,gyroz );
		  mcu_delay_ms(500);
	}
}





//



